<template>
  <el-card class="map-card" shadow="hover">
    <template #header>
      <div class="card-header">
        <span>设备分布地图</span>
        <div class="header-controls">
          <el-input v-model="searchKeyword" placeholder="请输入地址搜索" class="search-input" @keyup.enter="handleSearch">
            <template #append>
              <el-button @click="handleSearch">搜索</el-button>
            </template>
          </el-input>
          <el-button-group class="map-type-group">
            <el-button :type="mapType === '3D' ? 'primary' : ''" @click="switchMapType('3D')">3D</el-button>
            <el-button :type="mapType === '2D' ? 'primary' : ''" @click="switchMapType('2D')">2D</el-button>
            <el-button :type="mapType === 'satellite' ? 'primary' : ''" @click="switchMapType('satellite')">卫星</el-button>
          </el-button-group>
        </div>
      </div>
    </template>
    <div class="map-wrapper">
      <div ref="mapContainer" class="map-container"></div>
      <div class="map-controls">
        <button class="control-btn auto-refresh" :class="{ active: autoRefreshEnabled }" @click="toggleAutoRefresh">
          {{ autoRefreshEnabled ? '⏹️ 关闭实时' : '🔄 开启实时' }}
        </button>
        <button class="control-btn refresh" :disabled="isRefreshing" @click="refreshDevices">
          {{ isRefreshing ? '🔄 刷新中...' : '🔄 实时刷新' }}
        </button>
        <button class="control-btn national" @click="resetToNational">🌍 全国视图</button>
        <button class="control-btn online" @click="showOnline">✅ 在线设备</button>
        <button class="control-btn offline" @click="showOffline">⛔ 离线设备</button>
        <button class="control-btn maintenance" @click="showMaintenance">🔧 维修设备</button>
      </div>
      <div class="status-panel">
        <div class="status-item online">在线：{{ statusCount[2] }}</div>
        <div class="status-item offline">离线：{{ statusCount[1] }}</div>
        <div class="status-item maintenance">维护：{{ statusCount[4] + statusCount[5] }}</div>
        <div class="status-item fault">故障：{{ statusCount[3] }}</div>
        <div class="status-item unused">未使用：{{ statusCount[0] }}</div>
      </div>
      <transition name="fade">
        <div v-if="loading" class="loading">🌍 地图初始化中...</div>
      </transition>
    </div>
  </el-card>
</template>

<script setup lang="ts">
import { ref, onMounted, onUnmounted, getCurrentInstance } from 'vue';
import { geocode, regeocode } from '@/api/vending/map';
import { listLocation } from '@/api/vending/location';

const { proxy } = getCurrentInstance();

// 地图相关
const mapContainer = ref<HTMLElement>();
const loading = ref(true);
const isMounted = ref(true);
const markers = ref([]);
const isRefreshing = ref(false);
const defaultCenter = ref(null);
const xy = ref(null);
const defaultZoom = 5;
const filterState = ref('');
const statusCount = ref({ 0: 0, 1: 0, 2: 0, 3: 0, 4: 0, 5: 0 });
const autoRefreshEnabled = ref(false);
const autoRefreshInterval = ref(null);
const searchKeyword = ref('');
const mapType = ref('3D');
let satelliteLayer: any = null;

let map: any = null;
let geocoder: any = null;
let marker: any = null;

// 搜索地址
const handleSearch = async () => {
  if (!searchKeyword.value) return;

  try {
    // 调用后端地理编码 API
    const response = await geocode(searchKeyword.value);
    console.log(response);

    if (response.code === 200 && response.data) {
      const data = response.data;
      if (!data.longitude || !data.latitude) {
        proxy.$modal.msgError('地址解析失败：无效的位置信息');
        return;
      }

      // 移动地图到搜索位置
      map.setCenter([data.longitude, data.latitude]);
      map.setZoom(15);

      // 显示地址信息
      const infoWindow = new window.AMap.InfoWindow({
        content: `<div class="info-window">
          <h4>${data.formattedAddress}</h4>
          <p>${data.province} ${data.city}</p>
          <p>${data.district} ${data.street || ''}</p>
          <p>经度：${data.longitude.toFixed(6)} 纬度：${data.latitude.toFixed(6)}</p>
        </div>`,
        offset: new window.AMap.Pixel(0, -30)
      });
      infoWindow.open(map, [data.longitude, data.latitude]);

      // 获取周边信息
      const nearbyResponse = await regeocode(Number(data.longitude), Number(data.latitude));

      if (nearbyResponse.code === 200 && nearbyResponse.data) {
        const pois = nearbyResponse.data.pois || [];
        if (pois.length > 0) {
          const nearbyContent = pois
            .map(
              (poi: any) =>
                `<div class="nearby-item">
              <h5>${poi.name || '未知地点'}</h5>
              <p>${poi.address || '无地址信息'}</p>
              <p>距离：${poi.distance || 0}米</p>
            </div>`
            )
            .join('');

          infoWindow.setContent(`<div class="info-window">
            <h4>${data.formattedAddress}</h4>
            <p>${data.province} ${data.city}</p>
            <p>${data.district} ${data.street || ''}</p>
            <p>经度：${data.longitude.toFixed(6)} 纬度：${data.latitude.toFixed(6)}</p>
            <div class="nearby-list">
              <h5>周边地点：</h5>
              ${nearbyContent}
            </div>
          </div>`);
        }
      }
    } else {
      proxy.$modal.msgError(response.msg || '未找到该地址');
    }
  } catch (error) {
    console.error('地址搜索失败:', error);
    proxy.$modal.msgError('地址搜索失败，请稍后重试');
  }
};

// 切换地图类型
const switchMapType = (type: string) => {
  mapType.value = type;
  if (type === 'satellite') {
    if (!satelliteLayer) {
      satelliteLayer = new window.AMap.TileLayer.Satellite();
      map.add(satelliteLayer);
    }
  } else {
    if (satelliteLayer) {
      map.remove(satelliteLayer);
      satelliteLayer = null;
    }
    // 使用 setPitch 和 setRotation 来控制 3D 效果
    if (type === '3D') {
      map.setPitch(60);
      map.setRotation(0);
    } else {
      map.setPitch(0);
      map.setRotation(0);
    }
  }
};

// 初始化地图
const initMap = () => {
  if (!mapContainer.value) return;

  try {
    map = new window.AMap.Map(mapContainer.value, {
      zoom: 5,
      center: [116.397428, 39.90923],
      viewMode: '3D',
      pitch: 60, // 设置初始俯仰角
      resizeEnable: true,
      mapStyle: 'amap://styles/normal',
      doubleClickZoom: true // 启用双击放大
    });

    // 添加地图控件
    map.addControl(new window.AMap.Scale());
    map.addControl(
      new window.AMap.ToolBar({
        position: 'RB'
      })
    );
    map.addControl(
      new window.AMap.MapType({
        position: 'RT'
      })
    );

    // 添加双击事件监听
    map.on('dblclick', (e: any) => {
      const zoom = map.getZoom();
      map.setZoom(zoom + 1);
    });

    // 初始化地理编码
    geocoder = new window.AMap.Geocoder({
      city: '全国'
    });

    loading.value = false;
  } catch (error) {
    console.error('地图初始化失败:', error);
    loading.value = false;
  }
};

// 控制方法
const toggleAutoRefresh = () => {
  autoRefreshEnabled.value = !autoRefreshEnabled.value;
  if (autoRefreshEnabled.value) {
    autoRefreshInterval.value = setInterval(() => {
      refreshDevices();
    }, 5000); // 每5秒刷新一次
  } else {
    clearInterval(autoRefreshInterval.value);
  }
};

const refreshDevices = async () => {
  if (isRefreshing.value) return;
  isRefreshing.value = true;
  try {
    // 清除现有标记
    markers.value.forEach((marker: any) => {
      marker.setMap(null);
    });
    markers.value = [];

    // 重新获取并显示设备位置
    await showDeviceLocations();
  } finally {
    isRefreshing.value = false;
  }
};

const resetToNational = () => {
  if (!map) return;
  map.setCenter([116.397428, 39.90923]);
  map.setZoom(4.8);
  filterState.value = ''; // 清除过滤状态

  // 显示所有设备
  markers.value.forEach((marker: any) => {
    marker.setMap(map);
  });

  // 更新按钮状态
  updateButtonStates();
};

const showOnline = () => {
  filterState.value = filterState.value === 'online' ? '' : 'online';
  filterDevices();
};

const showOffline = () => {
  filterState.value = filterState.value === 'offline' ? '' : 'offline';
  filterDevices();
};

const showMaintenance = () => {
  filterState.value = filterState.value === 'maintenance' ? '' : 'maintenance';
  filterDevices();
};

// 过滤设备显示
const filterDevices = () => {
  if (!markers.value.length) return;

  markers.value.forEach((marker: any) => {
    const device = marker.getExtData();
    if (!device) return;

    let shouldShow = true;
    switch (filterState.value) {
      case 'online':
        shouldShow = device.device.status === 2; // 在线
        break;
      case 'offline':
        shouldShow = device.device.status === 1; // 离线
        break;
      case 'maintenance':
        shouldShow = device.device.status === 4 || device.device.status === 5; // 维护中或待维护
        break;
      default:
        shouldShow = true;
    }

    marker.setMap(shouldShow ? map : null);
  });

  // 更新按钮状态
  updateButtonStates();
};

// 更新按钮状态
const updateButtonStates = () => {
  const buttons = document.querySelectorAll('.control-btn');
  buttons.forEach((btn: any) => {
    if (btn.classList.contains(filterState.value)) {
      btn.classList.add('active');
    } else {
      btn.classList.remove('active');
    }
  });
};

// 修改 showDeviceLocations 方法
const showDeviceLocations = async () => {
  try {
    const response = await listLocation({
      pageNum: 1,
      pageSize: 100
    });
    console.log(response);
    if (response.code === 200 && response.rows) {
      // 重置状态计数
      statusCount.value = {
        0: 0, // 未使用
        1: 0, // 离线
        2: 0, // 在线
        3: 0, // 故障
        4: 0, // 维护中
        5: 0 // 待维护
      };

      // 统计设备状态
      response.rows.forEach((device: any) => {
        const status = device.device.status;
        if (statusCount.value[status] !== undefined) {
          statusCount.value[status]++;
        }
      });

      // 将设备列表分成每批3个
      const batchSize = 3;
      const batches = [];
      for (let i = 0; i < response.rows.length; i += batchSize) {
        batches.push(response.rows.slice(i, i + batchSize));
      }

      // 分批处理设备
      for (const batch of batches) {
        await Promise.all(
          batch.map(async (device: any) => {
            const marker = new window.AMap.Marker({
              position: [device.longitude, device.latitude],
              map: map,
              title: device.location,
              extData: device,
              icon: new window.AMap.Icon({
                size: new window.AMap.Size(25, 34),
                image: 'https://webapi.amap.com/theme/v1.3/markers/n/mark_b.png',
                imageSize: new window.AMap.Size(25, 34)
              })
            });

            // 添加信息窗体
            const infoWindow = new window.AMap.InfoWindow({
              content: `<div class="info-window">
                <div class="device-header">
                  <div class="device-image">
                    <img
                      src="${device.device.imgUrl}"
                      alt="设备图片"
                      onerror="this.onerror=null;this.src='https://webapi.amap.com/theme/v1.3/markers/n/mark_b.png'"
                    />
                  </div>
                  <div class="device-title">
                    <h3>${device.device.deviceName}</h3>
                    <span class="status-tag status-${device.device.status}">${
                      device.device.status === 0
                        ? '未使用'
                        : device.device.status === 1
                          ? '离线'
                          : device.device.status === 2
                            ? '在线'
                            : device.device.status === 3
                              ? '故障'
                              : device.device.status === 4
                                ? '维护中'
                                : device.device.status === 5
                                  ? '待维护'
                                  : '未知'
                    }</span>
                  </div>
                </div>
                <div class="device-info">
                  <div class="info-item">
                    <i class="el-icon-document"></i>
                    <span>设备编号：${device.device.deviceNo}</span>
                  </div>
                  <div class="info-item">
                    <i class="el-icon-cpu"></i>
                    <span>设备型号：${device.device.model}</span>
                  </div>
                  <div class="info-item">
                    <i class="el-icon-connection"></i>
                    <span>通道数量：${device.device.channelCount}</span>
                  </div>
                  <div class="info-item">
                    <i class="el-icon-location"></i>
                    <span>位置：${device.location}</span>
                  </div>
                </div>
              </div>`,
              offset: new window.AMap.Pixel(0, window.innerWidth <= 768 ? 0 : -10),
              autoMove: true,
              closeWhenClickMap: true
            });

            // 绑定点击事件
            marker.on('click', () => {
              infoWindow.open(map, marker.getPosition());
            });

            markers.value.push(marker);
          })
        );

        // 每批处理完后稍微暂停一下，避免请求过于密集
        await new Promise((resolve) => setTimeout(resolve, 100));
      }

      // 应用当前过滤状态
      if (filterState.value) {
        filterDevices();
      }

      // 如果有设备，将地图中心设置为第一个设备的位置
      if (response.rows.length > 0) {
        map.setCenter([response.rows[0].longitude, response.rows[0].latitude]);
        // 根据设备数量调整缩放级别
        if (response.rows.length === 1) {
          map.setZoom(15);
        } else if (response.rows.length <= 5) {
          map.setZoom(13);
        } else if (response.rows.length <= 20) {
          map.setZoom(11);
        } else {
          map.setZoom(9);
        }
      }
    }
  } catch (error) {
    console.error('获取设备位置失败:', error);
    proxy.$modal.msgError('获取设备位置失败，请稍后重试');
  }
};

// 在组件挂载时初始化地图并显示设备位置
onMounted(() => {
  // 加载高德地图脚本
  const script = document.createElement('script');
  script.src = `https://webapi.amap.com/maps?v=2.0&key=44f91bca5fc95f3e79620c2d50bbfaed&plugin=AMap.Scale,AMap.ToolBar,AMap.MapType,AMap.Satellite,AMap.Geocoder,AMap.TileLayer.Satellite`;
  script.async = true;
  script.onload = () => {
    initMap();
    // 等待地图初始化完成后显示设备位置
    setTimeout(() => {
      showDeviceLocations();
    }, 1000);
  };

  script.onerror = () => {
    console.error('地图脚本加载失败');
    loading.value = false;
  };
  document.head.appendChild(script);
});

onUnmounted(() => {
  isMounted.value = false;
  if (map) {
    map.destroy();
  }
  if (autoRefreshInterval.value) {
    clearInterval(autoRefreshInterval.value);
  }
});
</script>

<style lang="scss">
.map-card {
  width: 100%;
  height: 100%;
  border-radius: 8px;
  overflow: hidden;

  .card-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    flex-wrap: wrap;
    gap: 12px;

    .header-controls {
      display: flex;
      gap: 12px;
      align-items: center;
      flex-wrap: wrap;

      .search-input {
        width: 300px;
      }

      .map-type-group {
        display: flex;
        gap: 4px;
      }
    }
  }

  .map-wrapper {
    position: relative;
    width: 100%;
    height: calc(100vh - 200px);
    min-height: 500px;

    .map-container {
      width: 100%;
      height: 100%;
    }

    .map-controls {
      position: absolute;
      top: 110px;
      right: 20px;
      display: flex;
      flex-direction: column;
      gap: 8px;
      z-index: 100;

      .control-btn {
        padding: 8px 12px;
        border: none;
        border-radius: 4px;
        background: white;
        box-shadow: 0 2px 6px rgba(0, 0, 0, 0.1);
        cursor: pointer;
        font-size: 14px;
        transition: all 0.3s;
        white-space: nowrap;

        &:hover {
          background: #f5f7fa;
        }

        &.active {
          background: #409eff;
          color: white;
        }

        &:disabled {
          opacity: 0.6;
          cursor: not-allowed;
        }
      }
    }

    .status-panel {
      position: absolute;
      top: 30px;
      left: 20px;
      bottom: auto;
      display: flex;
      gap: 12px;
      padding: 12px;
      background: white;
      border-radius: 8px;
      box-shadow: 0 2px 6px rgba(0, 0, 0, 0.1);
      // z-index: 100;

      .status-item {
        padding: 4px 12px;
        border-radius: 4px;
        font-size: 14px;
        white-space: nowrap;

        &.online {
          background: #67c23a;
          color: white;
        }

        &.offline {
          background: #909399;
          color: white;
        }

        &.maintenance {
          background: #e6a23c;
          color: white;
        }

        &.fault {
          background: #f56c6c;
          color: white;
        }

        &.unused {
          background: #909399;
          color: white;
        }
      }
    }

    .loading {
      position: absolute;
      top: 50%;
      left: 50%;
      transform: translate(-50%, -50%);
      padding: 12px 24px;
      background: rgba(255, 255, 255, 0.9);
      border-radius: 8px;
      box-shadow: 0 2px 6px rgba(0, 0, 0, 0.1);
      z-index: 100;
    }
  }
}

// 移动端适配
@media screen and (max-width: 768px) {
  .map-card {
    .card-header {
      flex-direction: column;
      align-items: stretch;
      gap: 8px;

      .header-controls {
        flex-direction: column;
        width: 100%;

        .search-input {
          width: 100%;
        }

        .map-type-group {
          width: 100%;
          justify-content: space-between;

          .el-button {
            flex: 1;
            padding: 8px 12px;
          }
        }
      }
    }

    .map-wrapper {
      height: calc(100vh - 280px);
      min-height: 400px;

      .map-controls {
        top: 110px;
        right: 10px;
        gap: 6px;

        .control-btn {
          padding: 6px 10px;
          font-size: 13px;
          position: relative;
          color: transparent !important;
          background-clip: padding-box;
          &::before {
            content: '';
            display: none;
          }
          &.auto-refresh::after {
            content: '实时';
            color: #333;
            position: absolute;
            left: 50%;
            top: 50%;
            transform: translate(-50%, -50%);
            width: 100%;
            text-align: center;
          }
          &.auto-refresh.active::after {
            content: '关闭';
          }
          &.refresh::after {
            content: '刷新';
            color: #333;
            position: absolute;
            left: 50%;
            top: 50%;
            transform: translate(-50%, -50%);
            width: 100%;
            text-align: center;
          }
          &.national::after {
            content: '全国';
            color: #333;
            position: absolute;
            left: 50%;
            top: 50%;
            transform: translate(-50%, -50%);
            width: 100%;
            text-align: center;
          }
          &.online::after {
            content: '在线';
            color: #333;
            position: absolute;
            left: 50%;
            top: 50%;
            transform: translate(-50%, -50%);
            width: 100%;
            text-align: center;
          }
          &.offline::after {
            content: '离线';
            color: #333;
            position: absolute;
            left: 50%;
            top: 50%;
            transform: translate(-50%, -50%);
            width: 100%;
            text-align: center;
          }
          &.maintenance::after {
            content: '维修';
            color: #333;
            position: absolute;
            left: 50%;
            top: 50%;
            transform: translate(-50%, -50%);
            width: 100%;
            text-align: center;
          }
        }
      }

      .status-panel {
        top: auto;
        bottom: 10px;
        left: 10px;
        right: 10px;
        flex-wrap: wrap;
        justify-content: space-between;
        padding: 8px;
        gap: 8px;

        .status-item {
          flex: 1;
          min-width: calc(50% - 4px);
          text-align: center;
          padding: 4px 8px;
          font-size: 12px;
        }
      }

      .loading {
        padding: 8px 16px;
        font-size: 14px;
      }
    }
  }
}

// 动画效果
.fade-enter-active,
.fade-leave-active {
  transition: opacity 0.3s;
}

.fade-enter-from,
.fade-leave-to {
  opacity: 0;
}

.info-window {
  padding: 0;
  max-width: 440px;
  border-radius: 10px;
  overflow: hidden;
  box-shadow: 0 6px 18px rgba(0, 0, 0, 0.13);

  .device-header {
    position: relative;
    padding: 20px 20px 12px 20px;
    background: linear-gradient(135deg, #f6f8fc 0%, #e9f0f7 100%);
    border-bottom: 1px solid #e8eef5;

    .device-image {
      width: 100%;
      height: 160px;
      margin-bottom: 12px;
      border-radius: 8px;
      overflow: hidden;
      background: #fff;
      box-shadow: 0 2px 8px rgba(0, 0, 0, 0.10);
      img {
        width: 100%;
        height: 100%;
        object-fit: contain;
      }
    }
    .device-title {
      display: block;
      h3 {
        margin: 0 0 6px 0;
        font-size: 18px;
        font-weight: 700;
        color: #2c3e50;
        max-width: 100%;
        white-space: normal;
        overflow: visible;
        text-overflow: unset;
      }
      .status-tag {
        display: inline-block;
        margin-top: 2px;
        padding: 3px 10px;
        border-radius: 5px;
        font-size: 13px;
        font-weight: 500;
      }
    }
  }
  .device-info {
    padding: 18px 20px 20px 20px;
    background: #fff;
    .info-item {
      display: flex;
      align-items: flex-start;
      margin-bottom: 12px;
      font-size: 14px;
      color: #606266;
      &:last-child {
        margin-bottom: 0;
      }
      i {
        margin-right: 8px;
        font-size: 16px;
        color: #409eff;
        flex-shrink: 0;
        margin-top: 2px;
      }
      span {
        white-space: nowrap;
        overflow: hidden;
        text-overflow: ellipsis;
      }
    }
  }
}

// 移动端适配
@media screen and (max-width: 768px) {
  .map-card {
    .info-window {
      max-width: 240px;

      .device-header {
        padding: 8px;

        .device-image {
          height: 80px;
          margin-bottom: 6px;
        }

        .device-title {
          h3 {
            font-size: 13px;
            max-width: 65%;
          }

          .status-tag {
            padding: 1px 4px;
            font-size: 11px;
          }
        }
      }

      .device-info {
        padding: 8px;

        .info-item {
          margin-bottom: 6px;
          font-size: 11px;

          i {
            font-size: 12px;
            margin-right: 4px;
          }
        }
      }
    }
  }
}
</style>
